import {ethers} from 'ethers'

const staking_addr = "0xDe180c0E980b6763cD4B3b120954CEfAa79f33B1"
const gmm_addr = "0xFB7f77680d3982d25615f0670e15eD80C9301b1F"
const factory_l1_addr = "0xC49A47ED862bf0E3cD88946cB6Bf491Dcb996dd9"
const ADDRESS0 = '0x0000000000000000000000000000000000000000'
const ROUTER = '0x10ED43C718714eb63d5aA57B78B54704E256024E'
const WBNB = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c'

const IStaking = [
	"function buy(address _parent, uint256 protectMin) external payable",
	"function getLPReward() public",
	"function getTokenReward() public",
	"function earned(address account) public view returns (uint256)",
	"function userRewardAlreadyPaid(address) external view returns (uint256)",
	"function balances(address) external view returns (uint256)",
	"function level_up(address _parent, uint256 protectMin) external payable",
]

const IGMM =[
	"function isInCoinHolders(address) external view returns (bool)"
]

const swapABI =[
		"function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts)",
        "function getAmountsIn(uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts)",
    ]

const isHolder = async () =>{
	if (!window.ethereum) return {error: true,msg: 'please connect wallet'}
	const provider = new ethers.providers.Web3Provider(window.ethereum)
	const account = await connectMetamask()
	if(typeof account !== 'string') return account
	
	const gmm = new ethers.Contract(gmm_addr, IGMM, provider)
	const res = await gmm.isInCoinHolders(account)
	return res
}

const connectMetamask = async () => {
    if (!window.ethereum) return {error: true,msg:"Please link to the wallet environment for use"}
    let addressArray;
    try {
        addressArray = await window.ethereum.request({
            method: "eth_requestAccounts",
        });
        if (addressArray.length !== 0) {
            return addressArray[0];
        }
    } catch (connectError) {
        return {
			error: true,
            msg: connectError,
        };
    }
};

const buy = async (bnb_amount, parent = ADDRESS0) =>{
	if (!window.ethereum) return {error: true,msg: 'please connect wallet'}
	const provider = new ethers.providers.Web3Provider(window.ethereum)
	const account = await connectMetamask()
	if(typeof account !== 'string') return account
	const balance = await provider.getBalance(account)
	const value = ethers.utils.parseEther(bnb_amount)
	if(balance.lte(value)) return {error: true,msg: '余额不足'}
	
	const signer = provider.getSigner()
	const stake = new ethers.Contract(staking_addr, IStaking, signer)
	
    const router = new ethers.Contract(ROUTER, swapABI, signer)
    const [, amount1] = await router.getAmountsOut(value.mul('30').div('100'), [WBNB, gmm_addr])
    console.log(amount1);
	const pMin = amount1.mul(993).div(1000);
	
	const tx = await stake.buy(parent,pMin, {value})
	const r = await tx.wait()
	return r
}

const getTotalIn = async () =>{
	if (!window.ethereum) return {error: true,msg: 'please connect wallet'}
	const provider = new ethers.providers.Web3Provider(window.ethereum)
	const account = await connectMetamask()
	if(typeof account !== 'string') return account
	
	const stake = new ethers.Contract(staking_addr, IStaking, provider)
	const balance = await stake.balances(account)
	const res = balance.mul(2)
	const res2 = ethers.utils.formatEther(res)
	return res2
}

const getRewardAlreadyPaid = async () =>{
	if (!window.ethereum) return {error: true,msg: 'please connect wallet'}
	const provider = new ethers.providers.Web3Provider(window.ethereum)
	const account = await connectMetamask()
	if(typeof account !== 'string') return account
	
	const stake = new ethers.Contract(staking_addr, IStaking, provider)
	const alreadyPaid = await stake.userRewardAlreadyPaid(account)
	const res2 = ethers.utils.formatEther(alreadyPaid)
	return res2
}

const getEarned = async () =>{
	if (!window.ethereum) return {error: true,msg: 'please connect wallet'}
	const provider = new ethers.providers.Web3Provider(window.ethereum)
	const account = await connectMetamask()
	if(typeof account !== 'string') return account
	
	const stake = new ethers.Contract(staking_addr, IStaking, provider)
	const earn = await stake.earned(account)
	const res2 = ethers.utils.formatEther(earn)
	return res2
}

const getLPReward = async () =>{
	if (!window.ethereum) return {error: true,msg: 'please connect wallet'}
	const provider = new ethers.providers.Web3Provider(window.ethereum)
	const signer = provider.getSigner()
	console.log('getLPReward')
	const stake = new ethers.Contract(staking_addr, IStaking, signer)
	const tx = await stake.getLPReward()
	const r = await tx.wait()
	return r
}

const getTokenReward = async () =>{
	if (!window.ethereum) return {error: true,msg: 'please connect wallet'}
	const provider = new ethers.providers.Web3Provider(window.ethereum)
	const signer = provider.getSigner()
	console.log('getTokenReward')
	const stake = new ethers.Contract(staking_addr, IStaking, signer)
	const tx = await stake.getTokenReward()
	const r = await tx.wait()
	return r
}
const getLevelUp = async (parent) =>{
	if (!window.ethereum) return {error: true,msg: 'please connect wallet'}
	const provider = new ethers.providers.Web3Provider(window.ethereum)
	const signer = provider.getSigner()
	console.log('level_up')
	const in_amount =  ethers.utils.parseEther('0.0005')
	const router = new ethers.Contract(ROUTER, swapABI, signer)
	const [, amount1] = await router.getAmountsOut(in_amount, [WBNB, gmm_addr])
	console.log(amount1);
	const pMin = amount1.mul(995).div(1000);
	
	const stake = new ethers.Contract(staking_addr, IStaking, signer)
	const tx = await stake.level_up(parent, pMin, {
		value:in_amount
	})
	const r = await tx.wait()
	return r
}


export {
connectMetamask,
buy,
getTotalIn,
getEarned,
getRewardAlreadyPaid,
ADDRESS0,
getTokenReward,
getLPReward,
isHolder,
getLevelUp
}